import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;

/**
 * Authors - Oren Bracha, Rony Lahav and Yehuda Eterman
 * 
 * this class manages the UDP connections for input and output
 *
 */
public class TCPManager implements Runnable {

	// This method is responsible for listening to the specific client and inform the server
	// for every data got from the client	
	public void run()
	{
		boolean stillHasToRun = true;
		
		int counter = 1;
		int myPort = -1;
		
		ServerSocket serverSocket = null;
		do {
			try	
			{
				// Try to listen for incoming tcp connection
				if (myPort != proj350.getMyTCPPort()){
					myPort = proj350.getMyTCPPort();
					if (serverSocket != null && !serverSocket.isClosed()){
						serverSocket.close();
					}
					serverSocket = new ServerSocket(proj350.getMyTCPPort());
				}
				
				//create new TCP socket
				Socket newSocket=null;
				if (proj350.inTrialMode  && counter <= proj350.CONN_ESTABLISH_ATTEMPTS_NUMBER)
				{
					++counter;
					serverSocket.setSoTimeout(proj350.getUpdateFrequency()*1000);
					newSocket = serverSocket.accept(); // Server waits for new connection request
					
					proj350.inTrialMode = false;
					
					if (!proj350.updaterThread.isAlive()){
						proj350.updaterThread.start();
					}
				}
				else
				{
					serverSocket.setSoTimeout(proj350.MANAGER_REFRESH_TIME);
					newSocket = serverSocket.accept(); // Server waits for new connection request
				}

				//starting TCPReceiverConnection
				TCPReceiverConnection tcpRecConn = new TCPReceiverConnection(newSocket,proj350.getNewUniqueID());
				Thread thread = new Thread(tcpRecConn);
				proj350.addThreadToLivingList(tcpRecConn.getUniqueID(), thread);
				thread.start();
			}
			catch(SocketTimeoutException e1){
				//shut down if this is in initial connection and we had a timeout
				if (proj350.inTrialMode  && counter == proj350.CONN_ESTABLISH_ATTEMPTS_NUMBER){
					stillHasToRun = false;
					proj350.shutDown = true;
				}
			}
			catch(IOException e2)
			{
			}
			
			try{
				//we sleep each time for a second until the sleeping time is over
				if (proj350.getSleepPeriod() > 0){
					Thread.sleep(proj350.getSleepPeriod()*1000);
				}
			}
			catch (InterruptedException e){
			}
		} while (!proj350.isShutDown() && stillHasToRun); // while not shut down
		
		if (serverSocket != null && !serverSocket.isClosed()){
			try{
				serverSocket.close();
			}
			catch(IOException e){
			}
		}
	}
}
